<?php

namespace App\Models\Order;

use App\Models\Setting;
use App\Services\Locale\Language;
use App\Services\MobileApp\AppEnv;
use App\Services\Utils\Guard;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

/**
 * Class OrderStatus
 * @property string customer_order_status_name
 * @property string order_status_id
 * @package App\Models\Order
 *
 * @mixin Builder
 */

class OrderStatus extends Model
{
    public static $order_status_id_to_be_shipped; // 待发货状态数组
    public static $order_status_id_to_be_received; // 待收货状态数组
    public static $order_status_id_all_order; // 全部订单状态数组
    public static $order_status_id_to_be_evaluate; // 待评价状态数组（只是已完成，没有验证是否有评价）

    const ORDER_STATUS_ID_PAID = 13; // 已支付

    const ORDER_STATUS_ID_DELETE = 18; // 订单已删除
    const ORDER_STATUS_ID_CANCEL = 7; // 订单已取消

    const ORDER_STATUS_ID_COMPLETE = 5; // 已完成


    const ORDER_STATUS_ID_PENDING = 1; // 待处理
    const ORDER_STATUS_ID_PROCESSING = 2; // 处理中

    const ORDER_STATUS_ID_DEFAULT = 0; // 默认的未付款订单状态
    const ORDER_STATUS_ID_SHIPPED = 3; // 已发货

    // App端，个人中心禁止显示的状态
    const ORDER_STATUS_ID_CANCEL_MAP = [
        self::ORDER_STATUS_ID_DELETE, self::ORDER_STATUS_ID_CANCEL
    ];

    const ORDER_STATUS_ALL_ORDER_ID = 19; // 全部订单

    protected $table = 'order_status';
    protected $guarded = [];

    protected $primaryKey = 'order_status_id';

    public $appends = ['customer_order_status_name'];

    /**
     * @param $order_status_id
     * @return int|null
     */
    public static function filterOrderStatusId($order_status_id)
    {
        if (is_numeric($order_status_id) && (int)$order_status_id !== self::ORDER_STATUS_ALL_ORDER_ID) {
            return (int)$order_status_id;
        } else {
            return null;
        }
    }

    /**
     * @return null
     */
    public function getCustomerOrderStatusNameAttribute()
    {
        $order_status_id = $this->attributes['order_status_id'];
        $order_status_name = $this->attributes['name'];

        return $this->getOrderStatusMap($order_status_id) ?? $order_status_name;
    }

    /**
     * @param $order_status_id
     * @return int|null|string
     */
    private function getOrderStatusMap($order_status_id)
    {
        $order_status_name_map = OrderFlowStatus::where('language_id', AppEnv::languageId())
            ->where('order_flow_status_id', '<>', OrderFlowStatus::ORDER_FLOW_STATUS_ID_ALL_ORDER)
            ->get()
            ->all();

        $order_status_name_default = null;
        foreach($order_status_name_map as $item)
        {
            if (in_array($order_status_id, $item['order_status_id_map'])) {

                $order_status_name_default = $item['name'];
                break;
            }
        }

        return $order_status_name_default;
    }

    /**
     * @return array
     */
    public static function getOrderStatusIdToBeShipped()
    {
        if (self::$order_status_id_to_be_shipped) {
            return self::$order_status_id_to_be_shipped;
        }

        $store_id = Guard::customer()->store_id;

        $payment_extensions = (new Extension)
            ->where('type', Extension::EXTENSION_TYPE_PAYMENT)
            ->get();

        $payment_setting_codes = $payment_extensions->map(function (Extension $extension) {
            return $extension->type . '_' . $extension->code;
        });

        $payment_setting_status_keys = $payment_setting_codes->map(function (string $extension) {
            return $extension . Extension::SETTING_CODE_SUFFIX;
        });

        $payment_setting_codes = (new Setting)
            ->where('store_id', $store_id)
            ->whereIn('code', $payment_setting_codes)
            ->whereIn('key', $payment_setting_status_keys)
            ->where('value', Setting::VALUE_STATUS_ON)
            ->pluck('code');//dd($payment_setting_codes);
//        $store_order_status_id_default = self::getStoreOrderStatusIdDefault();

        $payment_order_status_ids = (new Setting)->where('store_id', $store_id)
            ->whereIn('code', $payment_setting_codes)
            ->where(function($query){
                return $query->where('key', 'payment_alipay_order_status_id')
                    ->orWhere('key', 'payment_cod_order_status_id')
                    ->orWhere('key', 'payment_free_checkout_order_status_id')
                    ->orWhere('key', 'payment_wechat_pay_completed_status_id')
                    ->orWhere('key', 'payment_pp_express_completed_status_id');
            })
            ->pluck('value');

        $payment_order_status_ids = $payment_order_status_ids->unique()
            ->transform(function(string $payment_order_status_id){
                return (int)$payment_order_status_id;
            })
            ->values()
            ->all();

        self::$order_status_id_to_be_shipped = $payment_order_status_ids;

        return $payment_order_status_ids;
    }

    /**
     * @return int|mixed
     */
    public static function getStoreOrderStatusIdDefault()
    {
        $store_id = Guard::customer()->store_id;

        $config_order_status_id = (new setting)->where('store_id', $store_id)
            ->where('key', 'config_order_status_id')
            ->first()
            ->value ?? self::ORDER_STATUS_ID_PENDING;

        return $config_order_status_id;
    }

    /**
     * @return mixed
     */
    public static function getOrderStatusIdToBeReceived()
    {
        if (self::$order_status_id_to_be_received) {
            return self::$order_status_id_to_be_received;
        }

        $payment_setting_codes = (new Setting)
            ->where('store_id', AppEnv::storeId())
            ->where('key', 'config_processing_status')
            ->first();

        $order_status_ids = json_decode($payment_setting_codes->value, true);

        $order_status_ids = array_map(function($order_status_id){
            return (int)$order_status_id;
        }, $order_status_ids);

        self::$order_status_id_to_be_received = $order_status_ids;

        return $order_status_ids;
    }

    /**
     * @return array
     */
    public static function getOrderStatusIdAllOrder()
    {
        if (self::$order_status_id_all_order) {
            return self::$order_status_id_all_order;
        }

        $order_status_ids = self::where('order_status_id', '<>', self::ORDER_STATUS_ID_DELETE)
            ->where('language_id', AppEnv::languageId())
            ->pluck('order_status_id')
            ->all();

        self::$order_status_id_all_order = $order_status_ids;

        return $order_status_ids;
    }

    /**
     * @return mixed
     */
    public static function getOrderStatusIdsToBeEvaluate()
    {
        if (self::$order_status_id_to_be_evaluate) {
           return self::$order_status_id_to_be_evaluate;
        }

        $payment_setting_codes = (new Setting)
            ->where('store_id', AppEnv::storeId())
            ->where('key', 'config_complete_status')
            ->first();

        $order_status_ids = json_decode($payment_setting_codes->value, true);

        $order_status_ids = array_map(function($order_status_id){
            return (int)$order_status_id;
        }, $order_status_ids);

        self::$order_status_id_to_be_evaluate = $order_status_ids;

        return $order_status_ids;
    }

    /**
     * @return array
     */
    public static function getReturnProductOrderStatusIds()
    {
        $to_be_shipped_order_status_ids = self::getOrderStatusIdToBeShipped();
        $to_be_received_order_status_ids = self::getOrderStatusIdToBeReceived();
        $to_be_evaluate_order_status_ids = self::getOrderStatusIdsToBeEvaluate();

        return array_merge($to_be_shipped_order_status_ids, $to_be_received_order_status_ids, $to_be_evaluate_order_status_ids);
    }

}
